/*
 * src/port/strlcat.c
 *
 *	$OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $	*/

/*
 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "c.h"


/*
 * 将src附加到大小为siz的字符串dst（与strncat不同，siz是
 * dst的总大小，而不是剩余空间）。最多复制siz-1个字符。
 * 始终以NUL结束（除非siz <= strlen(dst)）。
 * 返回strlen(src) + MIN(siz, strlen(initial dst))。
 * 如果retval >= siz，表示发生了截断。
 */
size_t strlcat(char *fc_dst, const char *fc_src, size_t fc_siz)
{
	char	   *fc_d = fc_dst;
	const char *fc_s = fc_src;
	size_t		fc_n = fc_siz;
	size_t		fc_dlen;

	/* 找到dst的末尾，并调整剩余字节，但不要超出末尾 */
	while (fc_n-- != 0 && *fc_d != '\0')
		fc_d++;
	fc_dlen = fc_d - fc_dst;
	fc_n = fc_siz - fc_dlen;

	if (fc_n == 0)
		return (fc_dlen + strlen(fc_s));
	while (*fc_s != '\0')
	{
		if (fc_n != 1)
		{
			*fc_d++ = *fc_s;
			fc_n--;
		}
		fc_s++;
	}
	*fc_d = '\0';

	return (fc_dlen + (fc_s - fc_src));	/* 计数不包括NUL */
}
